Java 继承

第九篇关于 Java 的笔记.

一. 继承的相关概念

1. 继承的意义

在面向对象语言中, 类就是模板, 通过模板可以创造出各种对象. 有些对象有一些共同的属性和方法, 如果在每个类定义里面都写一遍, 就很麻烦. 可以通过继承超类, 然后再完善自身的类, 达到一样的目的而不用写那么多代码.

2. 继承的语法

1
2
3
4
class 子类 extends 父类名
{
...
}
  • 父类, 超类: 通常指直接上级
  • 基类: 通常指包括直接上级在内的 “上级的上级”

3. 基础的特点

  • 子类自动拥有父类声明为 public 和 protectedd 的成员
  • 在子类里面是没办法访问父类中私有成员的
  • 可以看成是子类里面有这个私有成员, 但是没有访问权限. 因为在子类里面, 可以调用父类的方法输出父类的私有成员

二. 继承条件下类的访问权限

  • public: 外界可以自由访问
  • private: 外界不可访问
  • protected: 子类中可以访问
  • default: 同一个包中的类可以访问

三. 构造函数的调用顺序

  • 因为继承之后, 有可能有些属性在子类中的构造函数中没有被初始化, 所以需要调用父类的构造函数来初始化.
  • 虽然没有调用父类的构造函数, 但是会隐式的调用父类中无参的构造函数.
  • 如果父类中没有无参的构造函数, 在子类中又没有调用其他构造函数, 那么就会出错. (跟 C++ 一样)
  • 在子类的构造函数中调用父类的构造函数, 必须是第一句就调用. (我认为是因为有些东西是在父类中初始化的)

四. 不可修改的类

这样的类就是不可修改的类, 它不能被继承

1
2
3
final class 类名{

}

五. 当直接输出一个对象引用时会发生什么?

当调用

1
System.out.println(new A());

首先会调用

1
public void println(Object x);

还有调用

1
public static String valueOf(Object obj);

以及

1
2
3
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

最后输出: inherit.A@7852e922

六. 子类和父类方法之间的关系

  • 扩充: 增加父类中没有的方法
  • 覆盖/重写: 修改父类中的方法(方法名, 参数, 返回值都相同)
  • 重载: 与父类方法的方法名相同, 但参数不同.

七. 重写 toString 方法

  • 在 + 运算中, 任何一个对象与 String 对象连接时, 都会隐式调用 toString 方法

八. 方法覆盖的要点

  • 形式一定要完全相同, 否则就变成重载了
  • 可以通过 super 调用超类中被覆盖的方法

九. 方法覆盖的语法规则

  1. 覆盖方法的允许访问范围不能小于原方法
  2. 覆盖方法所抛出的异常不能比原方法更多
  3. 声明为 final 的方法不允许覆盖
  4. 不能覆盖静态方法